package com.demo.arch.datapulsedemo.v3_reliable.steps;

import com.demo.arch.datapulsedemo.common.NotificationRecipient;
import com.demo.arch.datapulsedemo.v2_pipeline.core.PipelineContext;
import com.demo.arch.datapulsedemo.v2_pipeline.core.StepExecutionException;
import com.demo.arch.datapulsedemo.v2_pipeline.core.StepHandler;
import com.demo.arch.datapulsedemo.v3_reliable.client.EmailServiceClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * V3可靠邮件发送步骤（简化版）
 * 
 * 核心特性：
 * 1. 调用外部邮件服务（模拟Feign）
 * 2. 支持幂等性：已发送成功的不会重复发送
 * 3. 失败记录日志，不自动重试
 * 4. 部分失败不影响后续发送
 * 
 * @author DataPulse Team
 */
@Slf4j
@Component
@Order(4)
public class ReliableEmailSendStepHandler implements StepHandler {

  @Autowired
  private EmailServiceClient emailServiceClient;

  @Override
  public String getName() {
    return "可靠邮件发送";
  }

  @Override
  public int getOrder() {
    return 4;
  }

  @Override
  public void handle(PipelineContext context) throws StepExecutionException {
    log.info(">>> [{}] 开始执行", getName());

    try {
      // 构建邮件内容
      String subject = buildEmailSubject(context);
      String content = buildEmailContent(context);

      context.setEmailSubject(subject);
      context.setEmailContent(content);

      log.info("邮件主题: {}", subject);

      // 初始化成功邮箱集合（如果为空）
      if (context.getSuccessEmails() == null) {
        context.setSuccessEmails(new HashSet<>());
      }

      // 发送给所有接收人
      List<NotificationRecipient> recipients = context.getRecipients();
      int successCount = 0;
      int failCount = 0;
      List<String> failedEmails = new ArrayList<>();

      for (NotificationRecipient recipient : recipients) {
        String email = recipient.getEmail();

        // 幂等性检查：已发送成功的跳过
        if (context.getSuccessEmails().contains(email)) {
          log.info("邮件已发送给: {} <{}>, 跳过", recipient.getName(), email);
          successCount++;
          continue;
        }

        try {
          // 调用外部邮件服务
          EmailServiceClient.EmailResult result = emailServiceClient.sendEmail(
              email,
              recipient.getName(),
              subject,
              content,
              context.getExcelFilePath());

          if (result.isSuccess()) {
            // 记录成功
            context.getSuccessEmails().add(email);
            successCount++;
            log.info("✓ 邮件发送成功: {} <{}>", recipient.getName(), email);
          } else {
            // 外部服务返回失败
            failCount++;
            failedEmails.add(email);
            log.warn("✗ 邮件发送失败: {} <{}> - {}",
                recipient.getName(), email, result.getMessage());
          }

        } catch (Exception e) {
          // 调用异常
          failCount++;
          failedEmails.add(email);
          log.error("✗ 调用邮件服务异常: {} <{}> - {}",
              recipient.getName(), email, e.getMessage());
        }
      }

      // 保存统计结果
      context.setEmailSuccessCount(successCount);
      context.setEmailFailCount(failCount);

      log.info(">>> [{}] 完成，成功 {} 人，失败 {} 人",
          getName(), successCount, failCount);

      // 如果有失败，记录但不抛异常（允许任务继续完成）
      if (failCount > 0) {
        String warningMsg = String.format(
            "邮件部分发送失败：成功%d个，失败%d个。失败邮箱：%s。可通过重新执行任务重试。",
            successCount, failCount, String.join(", ", failedEmails));
        log.warn(warningMsg);
        context.setErrorMessage(warningMsg);
      }

    } catch (Exception e) {
      log.error(">>> [{}] 执行失败", getName(), e);
      throw new StepExecutionException(getName(), "邮件发送失败", e);
    }
  }

  @Override
  public boolean shouldExecute(PipelineContext context) {
    // 幂等性检查：如果所有邮件都已发送，跳过执行
    if (context.getSuccessEmails() != null &&
        context.getRecipients() != null &&
        context.getSuccessEmails().size() == context.getRecipients().size()) {
      log.info(">>> [{}] 所有邮件已发送，跳过执行", getName());
      return false;
    }
    return true;
  }

  /**
   * 构建邮件主题
   */
  private String buildEmailSubject(PipelineContext context) {
    return String.format(
        "%s - 数据报表 (%s)",
        context.getReportType(),
        LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  }

  /**
   * 构建邮件内容
   */
  private String buildEmailContent(PipelineContext context) {
    StringBuilder content = new StringBuilder();
    content.append("尊敬的用户：\n\n");
    content.append("附件是您需要的").append(context.getReportType()).append("数据报表，请查收。\n\n");
    content.append("报表信息：\n");
    content.append("- 报表类型：").append(context.getReportType()).append("\n");

    if (context.getOrderData() != null) {
      content.append("- 数据条数：").append(context.getOrderData().size()).append("\n");
    }

    content.append("- 生成时间：").append(
        LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("\n\n");

    content.append("此邮件由系统自动发送，请勿回复。\n");
    content.append("DataPulse团队");

    return content.toString();
  }
}